//
//  YCAudioStreamer.m
//  YCSchool
//
//  Created by Yanglixia on 16/5/15.
//  Copyright © 2016年 yanglinxia. All rights reserved.
//

#import "YCAudioStreamer.h"
#import <AVFoundation/AVFoundation.h>


@interface YCAudioStreamer ()
{
    BOOL _isPlaying;// 标记是否正在播放
    BOOL _isPrepared;// 标记播放器是否准备完成
}
@property (nonatomic ,strong) id playbackTimeObserver;
@property (nonatomic, retain) AVPlayer *audioPlayer;// 音乐播放器
@end

@implementation YCAudioStreamer


- (void)setAudioMetadataWithURL:(NSString *)urlString
{
    if (self.audioPlayer.currentItem)
    {
        //这里要移除监听,否则会出错!!
        //An instance 0x7faca54aeef0 of class AVPlayerItem was deallocated while key value observers were still registered with it.
        [self.audioPlayer.currentItem removeObserver:self forKeyPath:@"status"];
        [self.audioPlayer.currentItem removeObserver:self forKeyPath:@"loadedTimeRanges"];
        [self.audioPlayer removeTimeObserver:self.playbackTimeObserver];
        
    }
    // 根据指定的URL创建一个AVPlayerItem对象
    _isPlaying = YES;
    AVPlayerItem *currentItem = [[AVPlayerItem alloc] initWithURL:[NSURL URLWithString:urlString]];
    
    [currentItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
    // 监听loadedTimeRanges属性
    [currentItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
    
    // 根据给定的Item对象 替换音频播放器当前的item
    [self.audioPlayer replaceCurrentItemWithPlayerItem:currentItem];
}

// lazyLoding
- (AVPlayer*)audioPlayer
{
    if (!_audioPlayer)
    {
        self.audioPlayer = [[AVPlayer alloc] init];
    }
    return _audioPlayer;
}

+ (instancetype)sharedStreamer
{
    static YCAudioStreamer *streamer = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        streamer = [[self alloc] init];
        
    });
    return streamer;
}

- (instancetype) init
{
    if (self= [super init])
    {
        //初始化
        _isPlaying = NO;
        //监听播放结束
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleEndTimeNotifation:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
    }
    return self;
}

#pragma mark - audio Control

- (void)play
{
    if ([self isPrepared]  == YES)
    {
        [self.audioPlayer play];
        
        _isPlaying = YES;
    }
    
    //初始播放进度监听
    __weak typeof(self) weakSelf = self;
    
    self.playbackTimeObserver = [self.audioPlayer addPeriodicTimeObserverForInterval:CMTimeMake(1, 1) queue:NULL usingBlock:^(CMTime time) {
        
        //防崩溃
        if (weakSelf.url == nil)
        {
            YCLog(@"发送空地址!!!!!!!!!!!!!!!!------------------%@",weakSelf.url);
            return;
        }
        
        NSDictionary *progressTag = @{@"url":[NSString stringWithFormat:@"%@%@",weakSelf.url,weakSelf.add_time],
                                      @"value":@(CMTimeGetSeconds([self.audioPlayer currentItem].currentTime) / CMTimeGetSeconds([self.audioPlayer currentItem].duration)),
                                      };
        [[NSNotificationCenter defaultCenter] postNotificationName:@"downProgressChanged" object:progressTag userInfo:nil];
    }];
}

- (void)pause
{
    [self.audioPlayer pause];
    [[NSNotificationCenter defaultCenter] postNotificationName:@"audioPlayerPause" object:nil userInfo:nil];
    _isPlaying = NO;
}

- (void)stop
{
    // 设置播放器暂停然后进度跳到0秒
    [self pause];
    [self.audioPlayer seekToTime:CMTimeMake(0, self.audioPlayer.currentTime.timescale)];
    [self setAudioMetadataWithURL:nil];
    [[NSNotificationCenter defaultCenter] postNotificationName:@"audioPlayerStop" object:nil userInfo:nil];
    
    _isPlaying = NO;
    _isPrepared = NO;
}

- (void)setVolume:(float)volume
{
    self.audioPlayer.volume = volume;
}

- (float)volume
{
    return self.audioPlayer.volume;
}

- (float)totalTime
{
    return CMTimeGetSeconds([self.audioPlayer.currentItem duration]);
}

- (float)currentTime
{
    return CMTimeGetSeconds([self.audioPlayer.currentItem currentTime]);
}

- (void)seekToTime:(float)time
{
    [self pause];
    [self.audioPlayer seekToTime:CMTimeMakeWithSeconds(time, self.audioPlayer.currentTime.timescale)];
    [self play];
}

- (void)handleTimerAction:(NSTimer *)sender
{
    if (self.delegate && [self.delegate respondsToSelector:@selector(audioStramer:didPlayingWithProgress:)])
    {
        float progress = self.audioPlayer.currentTime.value / self.audioPlayer.currentTime.timescale;
        [self.delegate audioStramer:self didPlayingWithProgress:progress];
        self.totalTime = CMTimeGetSeconds([self.audioPlayer.currentItem duration]);
    }
}

#pragma mark 播放结束通知
- (void)handleEndTimeNotifation:(NSNotificationCenter*)notification
{
    //结束后改变url, 使之可以重复播放
    [self setAudioMetadataWithURL:nil];
    _isPlaying = NO;
    if ([self.delegate respondsToSelector:@selector(audioStramerFinishPlay)])
    {
        [self.delegate audioStramerFinishPlay];
    }
}

- (BOOL)isPlaying
{
    return _isPlaying;
}

- (BOOL)isPrepared
{
    return _isPrepared;
}

- (BOOL)isPlayingCurrentAudioWithURL:(NSString *)urlString
{
    NSString *currentURLString = [(AVURLAsset *) self.audioPlayer.currentItem.asset URL].absoluteString;
    
    return [currentURLString isEqualToString:urlString];
}

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{
    AVPlayerItem *playerItem = (AVPlayerItem *)object;
    if ([keyPath isEqualToString:@"status"])
    {
        if ([playerItem status] == AVPlayerStatusReadyToPlay)
        {
            
            YCLog(@"AVPlayerStatusReadyToPlay");
            if ([self.delegate respondsToSelector:@selector(audioStramerStartPlay)])
            {
                [self.delegate audioStramerStartPlay];
            }
            _isPrepared = YES;
            [self play];
        }
        else if ([playerItem status] == AVPlayerStatusFailed)
        {
            YCLog(@"AVPlayerStatusFailed");
        }
        
    }
    else if ([keyPath isEqualToString:@"loadedTimeRanges"])
    {
        // 计算缓冲进度
        NSTimeInterval timeInterval = [self availableDuration];
        CMTime duration = [self.audioPlayer currentItem].duration;
        CGFloat totalDuration = CMTimeGetSeconds(duration);
        NSDictionary *progressTag = @{@"url":[NSString stringWithFormat:@"%@%@",self.url,self.add_time],
                                      @"value":@(timeInterval / totalDuration),
                                      };
        //下载进度通知
        [[NSNotificationCenter defaultCenter] postNotificationName:@"progressChanged" object:progressTag userInfo:nil];
        //[self.videoProgress setProgress:timeInterval / totalDuration animated:YES];
    }
}

- (NSTimeInterval)availableDuration
{
    NSArray *loadedTimeRanges = [[self.audioPlayer currentItem] loadedTimeRanges];
    CMTimeRange timeRange = [loadedTimeRanges.firstObject CMTimeRangeValue];// 获取缓冲区域
    float startSeconds = CMTimeGetSeconds(timeRange.start);
    float durationSeconds = CMTimeGetSeconds(timeRange.duration);
    NSTimeInterval result = startSeconds + durationSeconds;// 计算缓冲总进度
    
    return result;
}

+ (NSString *)timeWithInteger:(NSInteger)time
{
    return [NSString stringWithFormat:@"%02li:%02li",time/60,time%60];
}





@end
